package com.tsd;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @ClassName: StartAppRunner
 * @Description: 服务初始化之后，自动执行方法
 * 注解@PostConstruct、实现CommandLineRunner接口、实现ApplicationRunner接口、实现ApplicationListener
 * 使用注解@PostConstruct是最常见的一种方式，存在的问题是如果执行的方法耗时过长，会导致项目在方法执行期间无法提供服务。
 * 实现CommandLineRunner接口 然后在run方法里面调用需要调用的方法即可，好处是方法执行时，项目已经初始化完毕，是可以正常提供服务的。
 * 实现ApplicationRunner接口和实现CommandLineRunner接口基本是一样的；唯一的不同是启动时传参的格式，CommandLineRunner对于参数格式没有任何限制，ApplicationRunner接口参数格式必须是：–key=value
 * 实现接口ApplicationListener方式和实现ApplicationRunner，CommandLineRunner接口都不影响服务，都可以正常提供服务，注意监听的事件，通常是ApplicationStartedEvent 或者ApplicationReadyEvent，其他的事件可能无法注入bean。
 * 四种方式的执行顺序
 * 注解方式@PostConstruct 始终最先执行
 * 如果监听的是ApplicationStartedEvent 事件，则一定会在CommandLineRunner和ApplicationRunner 之前执行。
 * 如果监听的是ApplicationReadyEvent 事件，则一定会在CommandLineRunner和ApplicationRunner 之后执行。
 * CommandLineRunner和ApplicationRunner 默认是ApplicationRunner先执行，如果双方指定了@Order 则按照@Order的大小顺序执行，大的先执行。
 * @Author: Hillpool
 * @Date: 2021/4/30 17:42
 * @Version: 1.0
 */
@Component
@Order(1)
public class StartAppRunner implements CommandLineRunner {

    private static final Logger LOGGER = LoggerFactory.getLogger(StartAppRunner.class);

    @Override
    public void run(String... args) throws Exception {
        LOGGER.info("《服务初始化执行处理》 start...");
        LOGGER.info("《服务初始化执行处理》 end...");
    }
}
